;; The first four lines of this file were added by Dracula.
;; They tell DrScheme that this is a Dracula Modular ACL2 program.
;; Leave these lines unchanged so that DrScheme can properly load this file.
#reader(planet "reader.rkt" ("cce" "dracula.plt") "modular" "lang")
(require "mbmptree.lisp")
(require "mavltree.lisp")
(require "icolorshift.lisp")

;the colorshift module will choose one specific RGB value and change
;it to a new value throughout the bmp file.
(module Mcolorshift
  (import Ibmptree)
  (import Iavltree)
  (include-book "list-utilities" :dir :teachpacks)
  (include-book "binary-io-utilities" :dir :teachpacks)
  
  ;Shift-pixel looks at one individual pixel and determines if it is equal to the
  ;RGB values that are specified. If so, then the values are changed to the new RGB value.
  ; 
  ;pre: color - the original list of r g b values from the pixel
  ;     newcolor - the new list of r g b values to go to the new pixel
  ;     r - red
  ;     g - green
  ;     b - blue
  ;
  ;post: a newly colored pixel
  (defun shift-pixel (color newcolor r g b)
    (let* ((rcurr (car color))
           (gcurr (cadr color))
           (bcurr (caddr color))
           (rnew (car newcolor))
           (gnew (cadr newcolor))
           (bnew (caddr newcolor)))
      (if (and (equal rcurr r) (equal gcurr g) (equal bcurr b))
          (list rnew gnew bnew)
          (list r g b))))
  
  ;color-shift-helper is the helper function to color-shift.  It processes the new pixels
  ;and inserts them into a new tree.
  ; 
  ;pre: tr - the tree in which to insert the pixels
  ;     color - the old color of the rgb list
  ;     newcolor - the new color of the rgb list
  ;     rowIndex -  the index of the row to which the pixel will be inserted
  ;     numRows - the number of rows in the image
  ;     colIndex - the index of the column to which the pixel will be inserted
  ;     numCols - the number of columns in the image
  ;     
  ;post: the new bitmap tree with selectively replaced colors
  (defun color-shift-helper (tr color newcolor rowIndex numRows colIndex numCols)
    (if (< rowIndex numRows)
        (if (< colIndex numCols)
            (let* ((px (get-pixel-color tr rowIndex colIndex))
                   (r  (car px))
                   (g  (cadr px))
                   (b  (caddr px)))
              (color-shift-helper (insert-pixel tr (list rowIndex colIndex (shift-pixel color newcolor r g b)))
                                  color newcolor rowIndex numRows (+ colIndex 1) numCols))
            (color-shift-helper tr color newcolor (+ rowIndex 1) numRows 0 numCols))
        tr))
  
  ;Color-shift takes a tree and calls its helper function to create a new image.
  ;
  ;pre: tree - the tree that is to be changed
  ;     oldr - the red value of the color that needs to be changed
  ;     oldg - the green value of the color that needs to be changed
  ;     oldb - the blue value of the color that needs to be changed
  ;     r    - the red value of the new color that will replace the old color
  ;     g    - the green value of the new color that will replace the old color
  ;     b    - the blue value of the new color that will replace the old color
  ;
  ;post: a new bitmap tree with the processed image
  (defun color-shift (tr oldr oldg oldb r g b)
    (let* ((numRows  (car (get-dimensions tr)))
           (numCols  (cdr (get-dimensions tr)))
           (color    (list oldr oldg oldb))
           (newcolor (list r g b)))
      (color-shift-helper tr color newcolor 0 numRows 0 numCols)))
  
  (export Icolorshift))
